

import $Element from '@/core/Element';
import { DOMcreateElement } from '@/core/jsxFactory';
import HColorPickerCreater from './HColorPicker';
import { DrageMove, EDrageDirection } from "@/core/events/DrageMove";
import { HSL2RGB } from "./colorService"
import ResultPad from './resultPad';
export default class ColorPicker extends $Element {
    private container: $Element;
    private HColorComponent: $Element;
    private colorArea: $Element;
    private colorTopArea: $Element;
    private HColorValue: number = 0;
    private LColorValue: number = 100;
    private SColorValue: number = 50;
    private dragColorPointer: $Element;
    private colorPickerBottom: $Element;
    private currentColorEle: $Element;
    private resultPad: ResultPad;
    private cancelButton: $Element;
    private confirmButton: $Element;
    private colors: {
        RGB: string,
        HSL: string,
        HEX: string
    } | null = null;

    private confirmCallBack!: (colors: {
        RGB: string,
        HSL: string,
        HEX: string
    } | null) => void;
    private watchCallBack!: (colors: {
        RGB: string,
        HSL: string,
        HEX: string
    } | null) => void;
    constructor(container: $Element) {
        super(<div className="color-picker">
            <div className="color-picker-top">
                <div className="color-picker-area"></div>
            </div>
            <div class="color-picker-bottom">
                <div className="color-picker-preview preview-item"></div>
            </div>
            <div>
                <button className="color-picker-confirm-button">确定</button>
                <button className="color-picker-cancel-button">取消</button>
            </div>
        </div>)
        this.container = container;
        this.HColorComponent = HColorPickerCreater(this.drageMoveHColorComponent.bind(this), this.mouseupHColorComponent.bind(this));
        this.container.appendChild(this);
        this.colorTopArea = new $Element(".color-picker-top");
        this.colorPickerBottom = new $Element(".color-picker-bottom");
        this.currentColorEle = new $Element(".color-picker-preview")
        this.resultPad = new ResultPad(this.colorPickerBottom);
        this.colorArea = new $Element(".color-picker-area");
        this.colorArea.setStyleWithProp("backgroundColor", `hsl(${this.HColorValue},${this.LColorValue}%,${this.SColorValue}%)`);
        this.colorTopArea.appendChild(this.HColorComponent);
        this.dragColorPointer = new $Element(<div className="color-picker-area-pointer"></div>);
        this.colorArea.appendChild(this.dragColorPointer);
        this.cancelButton = new $Element(".color-picker-cancel-button");
        this.confirmButton = new $Element(".color-picker-confirm-button");
        this.cancelButton.addEventListener("click", this.cancel.bind(this));
        const self = this;
        this.confirmButton.addEventListener("click", function (evt: Event) {
            self.confirmCallBack && self.confirmCallBack(self.colors);
            self.cancel();
        });
        this.cancelButton.addEventListener("click", this.cancel.bind(this));
        const colorPointerHandler = DrageMove(this.colorArea, this.dragColorPointer, {
            dragBothDirct: EDrageDirection.Both,
            forbidenOutRange: true,
            overflowHiden: true,
            range: [-9, 9, 9, -9],
            documentMove: true
        });
        colorPointerHandler.addEventEndHook("mousemove", this.colorPointerMove.bind(this));
    }
    colorPointerMove(evt: Event) {
        const event = evt as MouseEvent;
        const self: any = event.target;
        if (self == this.dragColorPointer.current) {
            const center = [
                self.offsetLeft + 9,
                self.offsetTop + 9
            ];
            const SLocation = [(center[0] + center[1]) / 2, (center[1] + center[0]) / 2],
                SPercent = Math.round((1 - Math.sqrt(Math.pow(SLocation[0], 2) + Math.pow(SLocation[1], 2)) / Math.sqrt(2 * Math.pow(self.parentNode.offsetWidth, 2))) * 100),
                LValue = self.offsetWidth / 2 + parseInt(self.style.left.replace("px", "")),
                LPercent = Math.round((LValue / self.parentNode.offsetWidth) * 100);

            this.LColorValue = LPercent;
            this.SColorValue = SPercent;
            this.setColor(true);
        }

    }
    colorAreaMouseup(evt: Event) {
        const event = evt as MouseEvent;
    }
    mouseupHColorComponent(evt: Event) {
        const event = evt as MouseEvent;
        const self: any = event.target;
        const currentTop = self.getAttribute("class") == "drag-bar" ? self.offsetHeight / 2 + parseInt(self.style.top.replace("px", "")) : event.offsetY;
        if (self.getAttribute("class") == "drag-bar") {
            const HBaseValue = self.offsetHeight / 2 + parseInt(self.style.top.replace("px", ""))
            this.HColorValue = Math.round(HBaseValue / self.parentNode.offsetHeight * 360);
        } else {
            this.HColorValue = Math.round(event.offsetY / self.offsetHeight * 360);
        }
        this.setColor();
        // this.colorArea.setStyleWithProp("backgroundColor", `hsl(${this.HColorValue},${this.LColorValue}%,${this.SColorValue}%)`);
    }
    drageMoveHColorComponent(evt: Event) {
        const event = evt as MouseEvent;
        const self: any = event.target;
        const HBaseValue = self.offsetHeight / 2 + parseInt(self.style.top.replace("px", ""));
        this.HColorValue = Math.round(HBaseValue / self.parentNode.offsetHeight * 360);
        this.setColor();

    }

    setColor(isPreview: boolean = false) {
        if (isPreview === false) {
            this.colorArea.setStyleWithProp("backgroundColor", `hsl(${this.HColorValue},${this.LColorValue}%,${this.SColorValue}%)`);
        }
        this.currentColorEle.setStyleWithProp("backgroundColor", `hsl(${this.HColorValue},${this.LColorValue}%,${this.SColorValue}%)`);
        // console.log(`set:${this.HColorValue},${this.LColorValue}%,${this.SColorValue}%`)
        const RGB = HSL2RGB(this.HColorValue, this.LColorValue / 100, this.SColorValue / 100);
        this.colors = {
            RGB: `grb(${RGB.decimal.join(",")})`,
            HSL: `hsl(${this.HColorValue},${this.LColorValue}%,${this.SColorValue}%)`,
            HEX: `${RGB.hex}`
        }
        this.watchCallBack && this.watchCallBack(this.colors);
        this.resultPad.setContent(this.colors);
    }
    watch(fn: (colors: {
        RGB: string,
        HSL: string,
        HEX: string
    } | null) => void) {
        this.watchCallBack = fn;
    }
    confirm(fn: (colors: {
        RGB: string,
        HSL: string,
        HEX: string
    } | null) => void) {
        this.confirmCallBack = fn;
    }
    cancel() {
        (new $Element(".color-picker")).destory();
    }

}